#pragma once

#include <mutex>
#include <condition_variable>
#include <vector>
#include <thread>
#include <queue>
#include <iostream>
#define NUM 3

template <class T>
class threadPool
{
public:
    // 用于给线程分发任务
    static void *handleTask(void *args) // 由于static的原因，没有this指针，需要传threadPool
    {

        threadPool<T> *td = static_cast<threadPool *>(args);
        while (true)
        {
            T runTask;
            {
                std::unique_lock<std::mutex> lock(td->_mutex);
                while (td->isQueueEmpty())
                {
                    td->_cond.wait(lock);
                }
                runTask = td->pop();                            
            }
            std::cout << "答案：" << runTask() << std::endl; // 执行
        }
        delete td;

        return nullptr;
    }

public: // 默认函数与线程
    void operator=(const threadPool &) = delete;
    threadPool(const threadPool &) = delete;

    threadPool(const int &num = NUM) : _num(num)
    {
        // 申请线程
        for (int i = 0; i < _num; ++i)
        {
            _threads.push_back(new std::thread(handleTask, this));
        }
    }
    ~threadPool()
    {
        for (const auto &t : _threads)
            delete t;
    }

public: // 简单接口
    bool isQueueEmpty() { return _taskQueue.empty(); }

public: //_taskQueue
    T pop()
    {
        T task = _taskQueue.front();
        _taskQueue.pop();
        return task;
    }
    void push(const T &newTask)
    {
        std::unique_lock<std::mutex> lock(_mutex);
        _taskQueue.push(newTask);
        _cond.notify_all();
    }

private:
    int _num;
    std::vector<std::thread *> _threads;
    std::queue<T> _taskQueue;      // 用于存储task
    std::mutex _mutex;             // c++的锁与条件变量不用初始化
    std::condition_variable _cond; // 阻塞当taskQueue没有任务时的线程
};
